Analysis

#ctf #competition #0xl4ugh

From 0xlaugh ctf.
this for the archive chall :
Micro_togive.zip

Given source code and i see the flag in

def authenticate_user(username, password):
    try:
        conn = mysql.connector.connect(
            host=mysql_host,
            user=mysql_user,
            password=mysql_password,
            database=mysql_db
        )

        cursor = conn.cursor()

        query = "SELECT * FROM users WHERE username = %s AND password = %s"
        cursor.execute(query, (username, password))

        result = cursor.fetchone()

        cursor.close()
        conn.close()

        return result  
    except mysql.connector.Error as error:
        print("Error while connecting to MySQL", error)
        return None
        
@app.route('/login', methods=['POST'])
def handle_request():
    try:
        username = request.form.get('username')
        password = hashlib.md5(request.form.get('password').encode()).hexdigest()
        # Authenticate user
        user_data = authenticate_user(username, password)

        if user_data:
            return "0xL4ugh{Test_Flag}"  
        else:
            return "Invalid credentials"  
    except:
        return "internal error happened"

We can see if we pass argument authentication user and fill the all form we get the flag. its easy right? , we can see the waf after this in index.php

for login :

		$username=$_POST['username'];
		$password=md5($_POST['password']);
        if(Check_Admin($username) && $_SERVER['REMOTE_ADDR']!=="127.0.0.1")
        {
	         die("Admin Login allowed from localhost only : )");
        }
        else
        {
			send_to_api(file_get_contents("php://input"));
        }   


We can see we cant bypass the localhost only, so we can put the payload admin:admin and pass the if(Check_Admin($username) , Buttt

function Check_Admin($input)
{
  
    $input=iconv('UTF-8', 'US-ASCII//TRANSLIT', $input);   // Just to Normalize the string to UTF-8
    
    if(preg_match("/admin/i",$input))
    {
        return true;
    }
    else
    {
        return false;
    }
}

its checking the username if containing admin or no 😥. so we cant pass the statement there. so how to bypass it?

Bypass Preg Match To send admin:admin

OK we know if we send admin:admin in the python server we got flag. but got validate in the Check_admin and localhost. so we can put our double username like this

username=admin&username=justdummy&password=admin&login-submit=

and boom we got the flag
Pasted image 20240210163224.png

Conclusion

The python server validate the first username, and the pregmatch php validate the latest username parameter.